home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 101 / CD-ROM 101.iso / compl / maya5ple / Install_MayaPLE5_English.exe / Maya / Data1.cab / flowAlongCurves.mel < prev    next >
Encoding:
Text File  |  2003-07-17  |  36.5 KB  |  990 lines

  1. // Copyright (C) 1997-2002 Alias|Wavefront,
  2. // a division of Silicon Graphics Limited.
  3. //
  4. // The information in this file is provided for the exclusive use of the
  5. // licensees of Alias|Wavefront.  Such users have the right to use, modify,
  6. // and incorporate this code into other products for purposes authorized
  7. // by the Alias|Wavefront license agreement, without fee.
  8. //
  9. // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  10. // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  11. // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  12. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  13. // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  14. // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. // PERFORMANCE OF THIS SOFTWARE.
  16. //
  17. //
  18. // Flow Along Curves
  19. //
  20. // Author: Robert Tesdahl
  21. // Date:   November 10, 1998
  22. //
  23. // Description:
  24. //
  25. //    For each selected curve, this clip effect creates an emitted particle
  26. // object that "flows" along the curve.  This is done by creating a
  27. // complicated goal setup.  This also works on curve-on-surface objects
  28. // by creating a world-space curve that follows the curve-on-curve with
  29. // the history.
  30. //
  31.  
  32. includeEffectsGlobals();
  33.  
  34. proc string flowAlongCurve( string $setName, string $curveName, int $controlSegmentCount, int $subSegmentCount, int $attachEmitterToCurve, float $emitterRate, float $randomMotionSpeed, float $lifespan, float $goalWeight )
  35. //
  36. // Description:
  37. //
  38. //    This MEL procedure takes a curve in the scene and creates the
  39. // following objects:
  40. //
  41. //    -   Emitter, E
  42. //    -   Particle object, P, being emitted from E
  43. //    -   Goal, G, for P
  44. //    -   A set of locators that drive the "shape" of the goal G
  45. //    -   Two ramps that also control the "shape" of G
  46. //
  47. //    The locators are set up to lie on the curve.  A subset of the
  48. // locators act as "key locations" on the curve for the rest.  The
  49. // remaining locators are linearly interpolated along the curve
  50. // between the "key" locators.  The locators define a goal "path"
  51. // for the particles in P.  They try to move along the path over their
  52. // lifespan.
  53. //
  54. //    At each of the locators, there is also a circle.  The circle is
  55. // "attached" to the curve both in position and in tangent.  These
  56. // circle define a tube around the curve that represents the thickness
  57. // of the goal path.  The particles' goal positions will be somewhere
  58. // within the approximate shape of this tube.
  59. //
  60. {
  61.     //
  62.     // This variable tells the effect whether or not to produce any
  63.     // output to let the user know how/what it is doing.  If it looks
  64.     // like the effect might take more than a minute to execute, then
  65.     // this is turned on so that the user does not think that Maya
  66.     // has hung.
  67.     //
  68.     int $showOutput = 0;
  69.     if( 1 )
  70.     {
  71.         $showOutput = 1;
  72.     }
  73.  
  74.     //
  75.     // "setArray" is the list of all of the objects or groups created.
  76.     // They will all be grouped together at the end of the procedure.
  77.     //
  78.     string $setArray[];
  79.     clear($setArray);
  80.  
  81.     //
  82.     // These are arrays to hold the names of the created locators.
  83.     //
  84.     string $controlLocatorArray[];
  85.     clear($controlLocatorArray);
  86.     string $subLocatorArray[];
  87.     clear($subLocatorArray);
  88.     string $paramLocatorArray[];
  89.     clear($paramLocatorArray);
  90.  
  91.     //
  92.     // These are arrays to hold the names of the created circle.
  93.     //
  94.     string $scalableCircleArray[];
  95.     clear($scalableCircleArray);
  96.     string $controlCircleArray[];
  97.     clear($controlCircleArray);
  98.     string $subCircleArray[];
  99.     clear($subCircleArray);
  100.     string $circleArray[];
  101.     clear($circleArray);
  102.  
  103.     if( $showOutput )
  104.     {
  105.         print("//\n");
  106.         print("// Applying the effect to \""+$curveName+"\"...\n");
  107.         print("//\n");
  108.     }
  109.  
  110.     //
  111.     // Set the base name for the objects created.  If no name was
  112.     // passed in, then use a default base name.  Create a group
  113.     // for the objects to go into.
  114.     //
  115.     string $setGroupName;
  116.     if( size($setName) == 0 )
  117.         $setGroupName = `group -empty -name ($curveName+"_flowGroup")`;
  118.     else
  119.         $setGroupName = `group -empty -name $setName`;
  120.  
  121.     string $currentSelectedList[] = `ls -sl`;
  122.     string $setGroupPath = $currentSelectedList[0];
  123.     setAttr -keyable 0 ($setGroupPath+".tx");
  124.     setAttr -keyable 0 ($setGroupPath+".ty");
  125.     setAttr -keyable 0 ($setGroupPath+".tz");
  126.     setAttr -keyable 0 ($setGroupPath+".rx");
  127.     setAttr -keyable 0 ($setGroupPath+".ry");
  128.     setAttr -keyable 0 ($setGroupPath+".rz");
  129.     setAttr -keyable 0 ($setGroupPath+".sx");
  130.     setAttr -keyable 0 ($setGroupPath+".sy");
  131.     setAttr -keyable 0 ($setGroupPath+".sz");
  132.     // setAttr -lock 1 ($setGroupPath+".tx");
  133.     // setAttr -lock 1 ($setGroupPath+".ty");
  134.     // setAttr -lock 1 ($setGroupPath+".tz");
  135.     // setAttr -lock 1 ($setGroupPath+".rx");
  136.     // setAttr -lock 1 ($setGroupPath+".ry");
  137.     // setAttr -lock 1 ($setGroupPath+".rz");
  138.     // setAttr -lock 1 ($setGroupPath+".sx");
  139.     // setAttr -lock 1 ($setGroupPath+".sy");
  140.     // setAttr -lock 1 ($setGroupPath+".sz");
  141.  
  142.     //
  143.     // Grab the tail of the unique path for this group to
  144.     // use as the base name.
  145.     //
  146.     string $pathNames[];
  147.     tokenize( $setGroupPath, "|", $pathNames );
  148.     $setGroupName = $pathNames[size($pathNames)-1];
  149.  
  150.     //
  151.     // get some information about the curve for use when setting
  152.     // locator parameters.
  153.     //
  154.     float $curveStart = `getAttr ($curveName+".minValue")`;
  155.     string $curveStartStr = ($curveName+".minValue");
  156.     float $curveEnd = `getAttr ($curveName+".maxValue")`;
  157.     string $curveEndStr = ($curveName+".maxValue");
  158.     float $curveRange = $curveEnd - $curveStart;
  159.     string $curveRangeStr = ("( "+$curveEndStr+" - "+$curveStartStr+" )");
  160.  
  161.     //
  162.     // Create the particle object
  163.     //
  164.     string $particleName;
  165.     string $particlePath;
  166.     {
  167.         if( $showOutput )
  168.         {
  169.             print("//    Creating the particle object...\n");
  170.         }
  171.  
  172.         string $resultArray[] = `particle -name ($setGroupName+"_particle")`;
  173.         $particleName = $resultArray[1];
  174.         $particlePath = ("|"+$resultArray[0]+"|"+$particleName);
  175.         $setArray[size($setArray)] = ("|"+$resultArray[0]);
  176.         addAttr -ln "maxDistance" -dt doubleArray $particlePath;
  177.         addAttr -ln "maxDistance0" -dt doubleArray $particlePath;
  178.         addAttr -ln "curveOffset" -dt vectorArray $particlePath;
  179.         addAttr -ln "curveOffset0" -dt vectorArray $particlePath;
  180.         addAttr -ln "randomPosition" -dt vectorArray $particlePath;
  181.         addAttr -ln "randomPosition0" -dt vectorArray $particlePath;
  182.         addAttr -ln "goalOffset" -dt vectorArray $particlePath;
  183.         addAttr -ln "goalOffset0" -dt vectorArray $particlePath;
  184.         addAttr -ln "goalPP" -dt doubleArray $particlePath;
  185.         addAttr -ln "goalPP0" -dt doubleArray $particlePath;
  186.         addAttr -ln "rampValues" -dt vectorArray $particlePath;
  187.         addAttr -ln "rampValues0" -dt vectorArray $particlePath;
  188.     
  189.         // In previous versions we added lifespan here.
  190.         // Now in 3.0 and later, we set mode to constant.
  191.         //
  192.         setAttr ($particlePath+".lifespanMode") 1;
  193.         setAttr ($particlePath+".lifespan") $lifespan;
  194.     
  195.         addAttr -ln "randomMotionSpeed" -min 0 -dv 0 $particlePath;
  196.         setAttr ($particlePath+".randomMotionSpeed") $randomMotionSpeed;
  197.         setAttr -keyable 1 ($particlePath+".randomMotionSpeed");
  198.     
  199.         string $creationExpr;
  200.         $creationExpr = ($particlePath+".goalPP = 0;\n");
  201.         $creationExpr += ("vector $idVector = "+$particlePath+".id;\n");
  202.         $creationExpr += ("vector $randomPosition = dnoise( $idVector * 10.0 ) * 100.0;\n");
  203.         $creationExpr += ($particlePath+".randomPosition = $randomPosition;\n");
  204.         $creationExpr += ("float $randomMotionSpeed = "+$particlePath+".randomMotionSpeed;\n");
  205.         $creationExpr += ("float $maxDistance = "+$particlePath+".maxDistance;\n");
  206.         $creationExpr += ("vector $curveOffset =\n");
  207.         $creationExpr += ("    dnoise( $randomPosition + ( time * $randomMotionSpeed ) ) *\n    $maxDistance;\n");
  208.         $creationExpr += ("vector $rampValues = "+$particlePath+".rampValues;\n");
  209.         $creationExpr += ($particlePath+".curveOffset =\n    "+$particlePath+".curveOffset;\n");
  210.         $creationExpr += ($particlePath+".goalOffset =\n");
  211.         $creationExpr += ("    $rampValues + $curveOffset;\n");
  212.         dynExpression -c -s $creationExpr $particlePath;
  213.     
  214.         string $runtimeExpr;
  215.         $runtimeExpr = ($particlePath+".goalPP = 1;\n");
  216.         $runtimeExpr += ("vector $randomPosition = "+$particlePath+".randomPosition;\n");
  217.         $runtimeExpr += ("float $randomMotionSpeed = "+$particlePath+".randomMotionSpeed;\n");
  218.         $runtimeExpr += ("float $maxDistance = "+$particlePath+".maxDistance;\n");
  219.         $runtimeExpr += ("vector $curveOffset =\n");
  220.         $runtimeExpr += ("    dnoise( $randomPosition + ( time * $randomMotionSpeed ) ) *\n    $maxDistance;\n");
  221.         $runtimeExpr += ("vector $rampValues = "+$particlePath+".rampValues;\n");
  222.         $runtimeExpr += ($particlePath+".curveOffset =\n    "+$particlePath+".curveOffset;\n");
  223.         $runtimeExpr += ("vector $goalOffset = $rampValues + $curveOffset;\n");
  224.         $runtimeExpr += ($particlePath+".goalOffset =\n");
  225.         $runtimeExpr += ("    $rampValues + $curveOffset;\n");
  226.         dynExpression -r -s $runtimeExpr $particlePath;
  227.     }
  228.  
  229.     //
  230.     // Create the emitter and connect the particle shape to it.
  231.     //
  232.     string $emitterPath;
  233.     {
  234.         if( $showOutput )
  235.         {
  236.             print("//    Creating the emitter...\n");
  237.         }
  238.         string $emitterNameArray[];
  239.         $emitterNameArray = `emitter -pos 0 0 0 -rate $emitterRate -speed 0 -type omni -name ($setGroupName+"_emitter")`;
  240.         string $emitterName = $emitterNameArray[0];
  241.         $emitterPath = ("|"+$emitterName);
  242.         setAttr ($emitterPath+".inheritsTransform") 0;
  243.         connectDynamic -em $emitterPath $particlePath;
  244.         $setArray[size($setArray)] = $emitterPath;
  245.     }
  246.  
  247.     //
  248.     // Create the array mapper to control the thickness of the
  249.     // goal path.
  250.     //
  251.     string $arrayMapperName;
  252.     string $distanceRampName;
  253.     {
  254.         string $arrayMapperNameArray[] = `arrayMapper -target $particlePath -destAttr maxDistance -inputV ageNormalized -type ramp`;
  255.         $arrayMapperName = $arrayMapperNameArray[0];
  256.         string $rampNameArray[] = `listConnections ($arrayMapperName+".computeNode")`;
  257.         select $rampNameArray[0];
  258.         rename ($setGroupName+"_distance");
  259.         $rampNameArray = `ls -sl`;
  260.         $distanceRampName = $rampNameArray[0];
  261.     }
  262.  
  263.     //
  264.     // Create the arrayMapper to control to shape of the
  265.     // goal path.
  266.     //
  267.     string $positionRampName;
  268.     {
  269.         $arrayMapperNameArray = `arrayMapper -target $particlePath -destAttr rampValues -inputV ageNormalized -type ramp`;
  270.         $arrayMapperName = $arrayMapperNameArray[0];
  271.         $rampNameArray = `listConnections ($arrayMapperName+".computeNode")`;
  272.         select $rampNameArray[0];
  273.         rename ($setGroupName+"_position");
  274.         $rampNameArray = `ls -sl`;
  275.         $positionRampName = $rampNameArray[0];
  276.     }
  277.  
  278.     string $goalLocatorPath = "";
  279.     //
  280.     // Create the goal locator and make it a goal of the particle shape
  281.     //
  282.     {
  283.         string $goalLocatorName = ($setGroupName+"_goal");
  284.         createPrimitive nullObject;
  285.         $goalLocatorName = `rename $goalLocatorName`;
  286.         $goalLocatorPath = ("|"+$goalLocatorName);
  287.         setAttr ($goalLocatorPath+".inheritsTransform") 0;
  288.         goal -g $goalLocatorPath -weight $goalWeight $particlePath;
  289.         hide $goalLocatorPath;
  290.     }
  291.  
  292.     //
  293.     // Add the control attributes to the group
  294.     //
  295.     {
  296.         if( $showOutput )
  297.         {
  298.             print("//    Adding controls to the main group...\n");
  299.         }
  300.  
  301.         //
  302.         // "displaySubsegments" turns on the display of the
  303.         // locators controled by the "key" locators.  Turing this
  304.         // on lets you see how compact the locators are along
  305.         // the curve.
  306.         //
  307.         addAttr -ln "displaySubsegments" -at bool $setGroupPath;
  308.         setAttr -keyable 1 ($setGroupPath+".displaySubsegments");
  309.         setAttr ($setGroupPath+".displaySubsegments") 0;
  310.     
  311.         //
  312.         // "editCircles" turns on the display of the
  313.         // circles that define the thickness of the goal path.
  314.         // This must be turned on in order to select the circles
  315.         // for scaling.  While this is turned on, the selection
  316.         // for the "key" locators is disables so that there is
  317.         // not confusion as to which is being editted.
  318.         //
  319.         addAttr -ln "displayAllCircles" -at bool $setGroupPath;
  320.         setAttr -keyable 1 ($setGroupPath+".displayAllCircles");
  321.         setAttr ($setGroupPath+".displayAllCircles") 0;
  322.  
  323.         //
  324.         // "displayThickness" turns on the display of the tube
  325.         // that defines the thickness of the goal path.
  326.         //
  327.         addAttr -ln "displayThickness" -at bool $setGroupPath;
  328.         setAttr -keyable 1 ($setGroupPath+".displayThickness");
  329.         setAttr ($setGroupPath+".displayThickness") 0;
  330.     
  331.         //
  332.         // The group's "lifespan" attribute is connected to the particle
  333.         // object's "lifespan" attribute.  This is just to make the
  334.         // attribute more accessible to the user by selecting the group.
  335.         //
  336.         addAttr -ln "lifespan" -min 0 $setGroupPath;  // still correct in 3.0 and later
  337.         setAttr -keyable 1 ($setGroupPath+".lifespan");
  338.         setAttr ($setGroupPath+".lifespan") $lifespan;
  339.         connectAttr ($setGroupPath+".lifespan") ($particlePath+".lifespan");
  340.         
  341.         //
  342.         // The group's "goalWeight" attribute is connected to the particle
  343.         // object's "goalWeight[0]" attribute.  This is just to make the
  344.         // attribute more accessible to the user by selecting the group.
  345.         //
  346.         addAttr -ln "goalWeight" -min 0 $setGroupPath;
  347.         setAttr -keyable 1 ($setGroupPath+".goalWeight");
  348.         setAttr ($setGroupPath+".goalWeight") $goalWeight;
  349.         connectAttr ($setGroupPath+".goalWeight") ($particlePath+".goalWeight[0]");
  350.         
  351.         //
  352.         // The group's "randomMotionSpeed" attribute is connected to the particle
  353.         // object's "randomMotionSpeed" attribute.  This is just to make the
  354.         // attribute more accessible to the user by selecting the group.
  355.         //
  356.         addAttr -ln "randomMotionSpeed" $setGroupPath;
  357.         setAttr -keyable 1 ($setGroupPath+".randomMotionSpeed");
  358.         setAttr ($setGroupPath+".randomMotionSpeed") $randomMotionSpeed;
  359.         connectAttr ($setGroupPath+".randomMotionSpeed") ($particlePath+".randomMotionSpeed");
  360.     
  361.         //
  362.         // The group's "emissionRate" attribute is connected to the emitter's
  363.         // "rate" attribute.  This is just to make the attribute more
  364.         // accessible to the user by selecting the group.
  365.         //
  366.         addAttr -ln "emissionRate" $setGroupPath;
  367.         setAttr -keyable 1 ($setGroupPath+".emissionRate");
  368.         setAttr ($setGroupPath+".emissionRate") $emitterRate;
  369.         connectAttr ($setGroupPath+".emissionRate") ($emitterPath+".rate");
  370.  
  371.         //
  372.         // "curveMin" and "curveMax" just show the values for
  373.         // the curve's minValue and maxValue attributes.  This
  374.         // helps the user place the control locators.  This can
  375.         // not be done automatically after the script has been
  376.         // run, since it would restrict the control that the
  377.         // user has.
  378.         //
  379.         addAttr -ln "curveMin" $setGroupPath;
  380.         setAttr -keyable 1 ($setGroupPath+".curveMin");
  381.         connectAttr $curveStartStr ($setGroupPath+".curveMin");
  382.         setAttr -lock 1 ($setGroupPath+".curveMin");
  383.  
  384.         addAttr -ln "curveMax" $setGroupPath;
  385.         setAttr -keyable 1 ($setGroupPath+".curveMax");
  386.         connectAttr $curveEndStr ($setGroupPath+".curveMax");
  387.         setAttr -lock 1 ($setGroupPath+".curveMax");
  388.     }
  389.  
  390.     //
  391.     // The expression to control the parametric spacing of the locators
  392.     // and circles will be stored in "paramExpression".
  393.     //
  394.     string $paramExpression = "";
  395.  
  396.     //
  397.     // The expression to control the scaling of the circles will be
  398.     // stored in "scaleExpression".
  399.     //
  400.     string $scaleExpression = "";
  401.     
  402.     //
  403.     // Create the locators and circles along the goal path.
  404.     // also set up the expressions needed to interpolate
  405.     // the locators with the "key" locators.
  406.     //
  407.     {
  408.         if( $showOutput )
  409.         {
  410.             print("//    Creating control objects...\n");
  411.         }
  412.  
  413.         //
  414.         // There has to be at least one control segment and
  415.         // 1 sub-segment.
  416.         //
  417.         $controlSegmentCount = max( $controlSegmentCount, 2 );
  418.         $subSegmentCount = max( $subSegmentCount, 2 );
  419.     
  420.         int $controlLocatorCount = $controlSegmentCount + 1;
  421.         int $totalSubLocatorCount = $controlSegmentCount * $subSegmentCount + 1;
  422.  
  423.         //
  424.         // For each control segment, we create all of the sub-locators
  425.         // and circles for that segment.
  426.         //
  427.         for( $i = 0; $i < $controlSegmentCount; $i ++ )
  428.         {
  429.             if( $showOutput )
  430.             {
  431.                 print("//       Creating control segment "+$i+"...\n");
  432.             }
  433.  
  434.             //
  435.             // This loop creates all of the sub-segment objects as well
  436.             // as the end "key" locators and circles for the segment.
  437.             // If this is the first time through the loop, then we
  438.             // also need to create the first "key" locator and circle
  439.             // on the path.
  440.             //
  441.             if( $i == 0 )
  442.             {
  443.                 string $locatorName = ($setGroupName+"_controlLocator_0");
  444.  
  445.                 //
  446.                 // Create the first "key" locator.
  447.                 // The parametric location of the first "key" locator is
  448.                 // the "minValue" attribute value for the curve.
  449.                 //
  450.                 float $percent = 0.0;
  451.                 paramLocator ($curveName+".u["+$curveStart+"]");
  452.                 pickWalk -d up;
  453.                 $locatorName = `rename $locatorName`;
  454.                 $paramLocatorArray[size($paramLocatorArray)] = $locatorName;
  455.                 addAttr -ln ("locator_0_pos") -min 0 $setGroupName;
  456.                 setAttr -keyable true ($setGroupName+".locator_0_pos");
  457.                 connectAttr ($setGroupName+".locator_0_pos") ($locatorName+".localPositionX");
  458.                 setAttr ($setGroupName+".locator_0_pos") $curveStart;
  459.     
  460.                 //
  461.                 // Create the first sub-locator.
  462.                 //
  463.                 int $subLocatorNumber = 0;
  464.                 string $subLocatorName = ($setGroupName+"_locator_0_0");
  465.                 createPrimitive nullObject;
  466.                 $subLocatorName = `rename $subLocatorName`;
  467.                 string $subLocatorPath = ("|"+$subLocatorName);
  468.                 scale 2 2 2;
  469.                 setAttr ($subLocatorPath+".inheritsTransform") 0;
  470.                 $controlLocatorArray[size($controlLocatorArray)] = $subLocatorPath;
  471.  
  472.                 //
  473.                 // Attach to path group's selection handle to a point
  474.                 // near the first contol locator.
  475.                 //
  476.                 createPrimitive nullObject;
  477.                 rename "SelectionLocal";
  478.                 string $sl[] = `ls -sl`;
  479.                 string $localSelection = $sl[0];
  480.  
  481.                 parent $localSelection $subLocatorName;
  482.                 $sl = `ls -sl`;
  483.                 string $localSelection = $sl[0];
  484.                 setAttr ($localSelection+".template") 1;
  485.                 setAttr ($localSelection+".visibility") 0;
  486.                 vector $randPos = sphrand(1);
  487.                 setAttr ($localSelection+".translate") -type double3 ($randPos.x) ($randPos.y) ($randPos.z);
  488.  
  489.                 createPrimitive nullObject;
  490.                 rename "SelectionLocator";
  491.                 $sl = `ls -sl`;
  492.                 string $selectionLocator = $sl[0];
  493.                 setAttr ($selectionLocator+".template") 1;
  494.                 setAttr ($selectionLocator+".visibility") 0;
  495.                 setAttr ($selectionLocator+".inheritsTransform") 0;
  496.                 $controlLocatorArray[size($controlLocatorArray)] = $selectionLocator;
  497.  
  498.                 select $localSelection $selectionLocator;
  499.                 pointConstraint -weight 1;
  500.                 setAttr ($setGroupPath+".displayHandle") 1;
  501.                 connectAttr ($selectionLocator+".translate") ($setGroupPath+".selectHandle");
  502.                 getAttr ($setGroupPath+".selectHandle");
  503.     
  504.                 //
  505.                 // Create the pointOnCurveInfo node that will drive
  506.                 // position od this sub-locator, and connect it's
  507.                 // "position" attribute to the sub-locator's "translate"
  508.                 // attribute.
  509.                 //
  510.                 string $subPocName = ($setGroupName+"_POC_0_0");
  511.                 $subPocName = `createNode pointOnCurveInfo -name $subPocName`;
  512.                 connectAttr ($curveName+".worldSpace[0]") ($subPocName+".inputCurve");
  513.                 setAttr ($subPocName+".turnOnPercentage") 0;
  514.                 connectAttr ($subPocName+".position") ($subLocatorPath+".translate");
  515.  
  516.                 //
  517.                 // If needed, attach the emitter to the first sub-locator's
  518.                 // position.
  519.                 //
  520.                 if( $attachEmitterToCurve == 1 )
  521.                 {
  522.                     connectAttr ($subLocatorPath+".translate") ($emitterPath+".translate");
  523.                 }
  524.  
  525.                 string $cCircleName[] = `circle -c 0 0 0 -nr 0 0 1 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 6 -ch 1 -name ("control_Circle_0")`;
  526.                 select $subLocatorPath $cCircleName[0];
  527.                 pointConstraint -weight 1;
  528.                 select $curveName $cCircleName[0];
  529.                 tangentConstraint -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpVector 0 1 0;
  530.                 setAttr -keyable 0 ($cCircleName[0]+".tx");
  531.                 setAttr -keyable 0 ($cCircleName[0]+".ty");
  532.                 setAttr -keyable 0 ($cCircleName[0]+".tz");
  533.                 setAttr -keyable 0 ($cCircleName[0]+".rx");
  534.                 setAttr -keyable 0 ($cCircleName[0]+".ry");
  535.                 setAttr -keyable 0 ($cCircleName[0]+".rz");
  536.                 setAttr -keyable 0 ($cCircleName[0]+".sy");
  537.                 setAttr -keyable 0 ($cCircleName[0]+".sz");
  538.                 setAttr -keyable 0 ($cCircleName[0]+".visibility");
  539.                 setAttr -lock 1 ($cCircleName[0]+".visibility");
  540.     
  541.                 //
  542.                 // Create the first circle and "attach" it to the curve
  543.                 // with point and tangent constraints.
  544.                 //
  545.                 string $circleName[] = `circle -c 0 0 0 -nr 0 0 1 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 6 -ch 1 -name ($setGroupName+"_circle_0_0")`;
  546.                 select $subLocatorPath $circleName[0];
  547.                 pointConstraint -weight 1;
  548.                 select $curveName $circleName[0];
  549.                 tangentConstraint -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpVector 0 1 0;
  550.                 $controlCircleArray[size($controlCircleArray)] = $circleName[0];
  551.                 $scalableCircleArray[size($scalableCircleArray)] = $cCircleName[0];
  552.                 $circleArray[size($circleArray)] = $circleName[0];
  553.         
  554.                 float $percent = 0.0;
  555.                 //
  556.                 // Add the expression lines that keep this sub-locator in the
  557.                 // same place as the first "key' locator.
  558.                 //
  559.                 $paramExpression += ($subPocName+".parameter =\n");
  560.                 $paramExpression += ("    "+($locatorName+".localPositionX")+";\n\n");
  561.     
  562.                 //
  563.                 // Add the expression lines to keep this circle scaled uniformly.
  564.                 //
  565.                 if( 1 )
  566.                 {
  567.                     $scaleExpression += ($circleName[0]+".scaleX =\n");
  568.                     $scaleExpression += ("    "+$cCircleName[0]+".scaleX;\n\n");
  569.                     $scaleExpression += ($cCircleName[0]+".scaleY =\n    "+$cCircleName[0]+".scaleZ =\n    "+$cCircleName[0]+".scaleX;\n");
  570.                     $scaleExpression += ($circleName[0]+".scaleY =\n    "+$circleName[0]+".scaleZ =\n    "+$circleName[0]+".scaleX;\n");
  571.                 }
  572.                 else
  573.                 {
  574.                     connectAttr ($cCircleName[0]+".scaleX") ($circleName[0]+".scaleX");
  575.                     connectAttr ($cCircleName[0]+".scaleX") ($cCircleName[0]+".scaleY");
  576.                     connectAttr ($cCircleName[0]+".scaleX") ($cCircleName[0]+".scaleZ");
  577.                     connectAttr ($circleName[0]+".scaleX") ($circleName[0]+".scaleY");
  578.                     connectAttr ($circleName[0]+".scaleX") ($circleName[0]+".scaleZ");
  579.                 }
  580.     
  581.                 //
  582.                 // Add an entry into the distance ramp for the parametric
  583.                 // location of this sub-locator and the scale value of this
  584.                 // circle.  This is what defines the thickness of the goal
  585.                 // path.
  586.                 //
  587.                 setAttr ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].position") $percent;
  588.                 setAttr -lock 1 ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].position");
  589.                 connectAttr ($circleName[0]+".scaleX") ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].colorR");
  590.     
  591.                 //
  592.                 // Add an entry into the position ramp for the parametric
  593.                 // location of this sub-locator and the translate of the
  594.                 // sub-locator.  This defines the shape of the goal path.
  595.                 //
  596.                 setAttr ($positionRampName+".colorEntryList["+$subLocatorNumber+"].position") $percent;
  597.                 setAttr -lock 1 ($positionRampName+".colorEntryList["+$subLocatorNumber+"].position");
  598.                 connectAttr ($subLocatorPath+".translate") ($positionRampName+".colorEntryList["+$subLocatorNumber+"].color");
  599.             }
  600.     
  601.             int $controlLocatorNumber = $i + 1;
  602.     
  603.             string $locatorName = ($setGroupName+"_controlLocator_"+$controlLocatorNumber);
  604.             string $previousPocName = ($setGroupName+"_controlLocator_"+$i);
  605.             string $PocName = ($setGroupName+"_controlLocator_"+$controlLocatorNumber);
  606.     
  607.             //
  608.             // Create the current "key" locator.
  609.             //
  610.             float $endPercent = (float)$controlLocatorNumber/(float)($controlSegmentCount);
  611.             paramLocator ($curveName+".u["+($curveStart + $endPercent*$curveRange)+"]");
  612.             pickWalk -d up;
  613.             $PocName = `rename $PocName`;
  614.             $paramLocatorArray[size($paramLocatorArray)] = $PocName;
  615.             addAttr -ln ("locator_"+($controlLocatorNumber)+"_pos") -min 0 $setGroupName;
  616.             setAttr -keyable true ($setGroupName+".locator_"+($controlLocatorNumber)+"_pos");
  617.             connectAttr ($setGroupName+".locator_"+($controlLocatorNumber)+"_pos") ($locatorName+".localPositionX");
  618.             setAttr ($setGroupName+".locator_"+($controlLocatorNumber)+"_pos") ($curveStart + $endPercent * $curveRange);
  619.     
  620.             string $startValStr = ($previousPocName+".localPositionX");
  621.             string $endValStr = ($PocName+".localPositionX");
  622.     
  623.             string $cCircleName[] = `circle -c 0 0 0 -nr 0 0 1 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 6 -ch 1 -name ("control_Circle_"+$controlLocatorNumber)`;
  624.             string $previousCCircleName = ("control_Circle_"+$i);
  625.             string $startScaleStr = ("|"+$previousCCircleName+".scaleX");
  626.             string $endScaleStr = ($cCircleName[0]+".scaleX");
  627.  
  628.             if( 1 )
  629.             {
  630.                 $scaleExpression += ($cCircleName[0]+".scaleY =\n    "+$cCircleName[0]+".scaleZ =\n    "+$cCircleName[0]+".scaleX;\n");
  631.             }
  632.             else
  633.             {
  634.                 connectAttr ($cCircleName[0]+".scaleX") ($cCircleName[0]+".scaleY");
  635.                 connectAttr ($cCircleName[0]+".scaleX") ($cCircleName[0]+".scaleZ");
  636.             }
  637.  
  638.             //
  639.             // Create all of the sub-locators between the current and
  640.             // previous "key" locators.  Create all of the circles
  641.             // in between as well
  642.             //
  643.             int $j;
  644.             for( $j = 1; $j <= $subSegmentCount; $j ++ )
  645.             {
  646.                 int $subLocatorNumber = ( $i * $subSegmentCount ) + $j;
  647.                 string $subLocatorName = ($setGroupName+"_locator_"+$i+"_"+$j);
  648.                 createPrimitive nullObject;
  649.                 $subLocatorName = `rename $subLocatorName`;
  650.                 string $subLocatorPath = ("|"+$subLocatorName);
  651.     
  652.                 string $circleName[] = `circle -c 0 0 0 -nr 0 0 1 -sw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 6 -ch 1 -name ($setGroupName+"_circle_"+$i+"_"+$j)`;
  653.                 select $subLocatorPath $circleName[0];
  654.                 pointConstraint -weight 1;
  655.                 select $curveName $circleName[0];
  656.                 tangentConstraint -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpVector 0 1 0;
  657.  
  658.                 //
  659.                 // For each locator, if it is the last locator in this
  660.                 // segment, then make it bigger.  These larger ones
  661.                 // indicate where the user can select to edit the
  662.                 // locations of the "key" locators.  If it is not the
  663.                 // last locator, then scale it down a little.
  664.                 //
  665.                 if( $j == $subSegmentCount )
  666.                 {
  667.                     select $subLocatorPath $cCircleName[0];
  668.                     pointConstraint -weight 1;
  669.                     select $curveName $cCircleName[0];
  670.                     tangentConstraint -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpVector 0 1 0;
  671.                     setAttr -keyable 0 ($cCircleName[0]+".tx");
  672.                     setAttr -keyable 0 ($cCircleName[0]+".ty");
  673.                     setAttr -keyable 0 ($cCircleName[0]+".tz");
  674.                     setAttr -keyable 0 ($cCircleName[0]+".rx");
  675.                     setAttr -keyable 0 ($cCircleName[0]+".ry");
  676.                     setAttr -keyable 0 ($cCircleName[0]+".rz");
  677.                     setAttr -keyable 0 ($cCircleName[0]+".sy");
  678.                     setAttr -keyable 0 ($cCircleName[0]+".sz");
  679.                     setAttr -keyable 0 ($cCircleName[0]+".visibility");
  680.                     setAttr -lock 1 ($cCircleName[0]+".visibility");
  681.  
  682.                     select $subLocatorPath;
  683.                     scale 2 2 2;
  684.                     $controlLocatorArray[size($controlLocatorArray)] = $subLocatorPath;
  685.                     $controlCircleArray[size($controlCircleArray)] = $circleName[0];
  686.                     $scalableCircleArray[size($scalableCircleArray)] = $cCircleName[0];
  687.                     $circleArray[size($circleArray)] = $circleName[0];
  688.                 }
  689.                 else
  690.                 {
  691.                     select $subLocatorPath;
  692.                     scale .5 .5 .5;
  693.                     $subLocatorArray[size($subLocatorArray)] = $subLocatorPath;
  694.                     $subCircleArray[size($subCircleArray)] = $circleName[0];
  695.                     $circleArray[size($circleArray)] = $circleName[0];
  696.                 }
  697.  
  698.                 //
  699.                 // Create the pointOnCurveInfo node that will use the
  700.                 // parametric locations of the "key" locators and set
  701.                 // the location of this sub-locator.
  702.                 //
  703.                 string $subPocName = ($setGroupName+"_controlLocator_"+$i+"_"+$j);
  704.                 $subPocName = `createNode pointOnCurveInfo -name $subPocName`;
  705.                 connectAttr ($curveName+".worldSpace[0]") ($subPocName+".inputCurve");
  706.                 setAttr ($subPocName+".turnOnPercentage") 0;
  707.         
  708.                 float $percent = (float)($j)/(float)($subSegmentCount);
  709.     
  710.                 $paramExpression += ($subPocName+".parameter =\n");
  711.                 $paramExpression += ("    "+$startValStr+" +\n");
  712.                 $paramExpression += ("    "+$percent+" * ( "+$endValStr+" -\n");
  713.                 $paramExpression += ("      "+$startValStr+" );\n\n");
  714.         
  715.                 $scaleExpression += ($circleName[0]+".scaleX =\n");
  716.                 $scaleExpression += ("    "+$startScaleStr+" +\n");
  717.                 $scaleExpression += ("    "+$percent+" * ( "+$endScaleStr+" -\n");
  718.                 $scaleExpression += ("      "+$startScaleStr+" );\n\n");
  719.                 if( 1 )
  720.                 {
  721.                     $scaleExpression += ($circleName[0]+".scaleY =\n    "+$circleName[0]+".scaleZ =\n    "+$circleName[0]+".scaleX;\n");
  722.                 }
  723.                 else
  724.                 {
  725.                     connectAttr ($circleName[0]+".scaleX") ($circleName[0]+".scaleY");
  726.                     connectAttr ($circleName[0]+".scaleX") ($circleName[0]+".scaleZ");
  727.                 }
  728.     
  729.                 connectAttr ($subPocName+".position") ($subLocatorPath+".translate");
  730.     
  731.                 $percent = (float)$subLocatorNumber/(float)($totalSubLocatorCount - 1);
  732.     
  733.                 setAttr ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].position") $percent;
  734.                 setAttr -lock 1 ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].position");
  735.                 connectAttr ($circleName[0]+".scaleX") ($distanceRampName+".colorEntryList["+$subLocatorNumber+"].colorR");
  736.     
  737.                 setAttr ($positionRampName+".colorEntryList["+$subLocatorNumber+"].position") $percent;
  738.                 setAttr -lock 1 ($positionRampName+".colorEntryList["+$subLocatorNumber+"].position");
  739.                 connectAttr ($subLocatorPath+".translate") ($positionRampName+".colorEntryList["+$subLocatorNumber+"].color");
  740.                 setAttr ($subLocatorPath+".inheritsTransform") 0;
  741.             }
  742.         }
  743.     }
  744.  
  745.     //
  746.     // Execute the expression command for the interpolating and the scaling
  747.     // expressions.
  748.     //
  749.     if( $showOutput )
  750.     {
  751.         print("//    Compiling parameter expression.  This may take several minutes...");
  752.     }
  753.     expression -ae 0 -s $paramExpression -name ($setGroupName+"_parameterExpression");
  754.     if( $showOutput )
  755.     {
  756.         print("\n");
  757.     }
  758.  
  759.     if( $showOutput )
  760.     {
  761.         print("//    Compiling scaling expression.  This may take several minutes...");
  762.     }
  763.     expression -ae 0 -s $scaleExpression -name ($setGroupName+"_scaleExpression");
  764.     if( $showOutput )
  765.     {
  766.         print("\n");
  767.     }
  768.  
  769.  
  770.     if( $showOutput )
  771.     {
  772.         print("//    Creating goal volume around the curve...\n");
  773.     }
  774.     //
  775.     // Loft a surface through all of the circles.  This surface represents
  776.     // the thickness of the goal path.
  777.     //
  778.     select $circleArray;
  779.     string $loftName[] = `loft -ch 1 -u 1 -c 0 -ar 1 -d 1 -rn 0 -po 0 -name ($setGroupName+"_distanceShell")`;
  780.     setAttr ($loftName[0]+".template") 1;
  781.     connectAttr ($setGroupPath+".displayThickness") ($loftName[0]+".visibility");
  782.  
  783.     if( $showOutput )
  784.     {
  785.         print("//    Grouping all of the objects together...\n");
  786.     }
  787.     //
  788.     // Group all of the circles together
  789.     //
  790.     select $scalableCircleArray;
  791.     string $scalableCircleGroupName = `group -name ($setGroupName+"_scalableCircles")`;
  792.     $scalableCircleGroupName = ("|"+$scalableCircleGroupName);
  793.     setAttr -lock 1 ($scalableCircleGroupName+".scale");
  794.  
  795.     select $controlCircleArray;
  796.     string $controlCircleGroupName = `group -name ($setGroupName+"_controlCircles")`;
  797.     $controlCircleGroupName = ("|"+$controlCircleGroupName);
  798.     setAttr -lock 1 ($controlCircleGroupName+".scale");
  799.  
  800.     select $subCircleArray;
  801.     string $subCircleGroupName = `group -name ($setGroupName+"_subCircles")`;
  802.     $subCircleGroupName = ("|"+$subCircleGroupName);
  803.     connectAttr ($setGroupPath+".displayAllCircles") ($subCircleGroupName+".visibility");
  804.     setAttr -lock 1 ($subCircleGroupName+".scale");
  805.  
  806.     select $controlCircleGroupName $subCircleGroupName;
  807.     string $circleGroupName = `group -name ($setGroupName+"_circles")`;
  808.     $circleGroupName = ("|"+$circleGroupName);
  809.     setAttr -lock 1 ($circleGroupName+".scale");
  810.     setAttr ($circleGroupName+".template") 1;
  811.  
  812.     select $circleGroupName $scalableCircleGroupName;
  813.     string $circlesName = `group -name "Circles"`;
  814.     string $sl[] = `ls -sl`;
  815.     $circlesName = $sl[0];
  816.  
  817.     //
  818.     // Group all of the locators together
  819.     //
  820.     select $controlLocatorArray;
  821.     string $controlLocatorGroupName = `group -name ($setGroupName+"_controlLocators")`;
  822.     $controlLocatorGroupName = ("|"+$controlLocatorGroupName);
  823.  
  824.     select $subLocatorArray;
  825.     string $subLocatorGroupName = `group -name ($setGroupName+"_subLocators")`;
  826.     $subLocatorGroupName = ("|"+$subLocatorGroupName);
  827.     connectAttr ($setGroupPath+".displaySubsegments") ($subLocatorGroupName+".visibility");
  828.  
  829.     select $controlLocatorGroupName $subLocatorGroupName;
  830.     string $locatorGroupName = `group -name ($setGroupName+"_locators")`;
  831.     $locatorGroupName = ("|"+$locatorGroupName);
  832.     setAttr ($locatorGroupName+".template") 1;
  833.  
  834.     select $locatorGroupName $goalLocatorPath;
  835.     string $locatorsName = `group -name "Locators"`;
  836.     $sl = `ls -sl`;
  837.     $locatorsName = $sl[0];
  838.  
  839.     select $curveName $loftName[0] $locatorsName $circlesName;
  840.     string $controlObjects = `group -name "ControlObjects"`;
  841.     $sl = `ls -sl`;
  842.     $setArray[size($setArray)] = $sl[0];
  843.  
  844.     //
  845.     // Parent all of the created objects under the main group.
  846.     //
  847.     select $setArray;
  848.     parent $setArray $setGroupPath;
  849.     select $setGroupPath;
  850.     setAttr ($setGroupPath+".inheritsTransform") 0;
  851.  
  852.     getAttr ($setGroupPath+".selectHandle");
  853.  
  854.     if( $showOutput )
  855.     {
  856.         print("// Done.\n");
  857.         print("//\n");
  858.     }
  859.  
  860.     //
  861.     // Return the name of the main group created
  862.     //
  863.     string $finalSelectionList[] = `ls -sl`;
  864.     return $finalSelectionList[0];
  865. }
  866.  
  867. global proc string[] flowAlongCurves( string $setName, int $controlSegmentCount, int $subSegmentCount, int $attachEmitterToCurve, float $emitterRate, float $randomMotionSpeed, float $lifespan, float $goalWeight )    // CAROL 5 4 1 20 .5 5 .5 //
  868. //
  869. // Description:
  870. //
  871. //    This procedure takes the selection list and filters out all of the
  872. // nurbsCurve typed objects.  For each selected curve, it then calls the
  873. // flowAlongCurve() procedure, passing along the other arguments to it.
  874. // If any of the selected curves are curve-on-surfaces, then the
  875. // "duplicateCurve" command is used to create a curve in the world,
  876. // and then the effect is run on the new curve.  Since the original
  877. // curve is still a part of the new curve's history, any changes to
  878. // it will be reflected in the new curve.
  879. //
  880. //    The return value for this procedure is a list of the newly
  881. // created groups that contain the objects used for the effect.
  882. //
  883. {
  884.     //
  885.     // "resultArray" keeps a list of the new groups created.
  886.     // "curveArray" will get filled with all of the currently
  887.     // selected curves.
  888.     //
  889.     string $resultArray[];
  890.     clear($resultArray);
  891.     string $curveArray[];
  892.     clear($curveArray);
  893.  
  894.     if( `licenseCheck -type complete` == 0 )
  895.     {
  896.         warning("You are not licensed to use the Flow Along Curves Effect.");
  897.         return $resultArray;
  898.     }
  899.  
  900.     $setName = removeAllWhiteSpace( $setName );
  901.  
  902.     //
  903.     // Save the selection list
  904.     //
  905.     string $currentSelection[] = `ls -sl`;
  906.  
  907.     //
  908.     // First get the selected curves
  909.     //
  910.     {
  911.         $curveArray = getSelectedList( "allCurves" );
  912.     
  913.         if( size($curveArray) == 0 )
  914.         {
  915.             warning("No curves selected.  Select one or more curves or the parent transforms of curves.");
  916.             return( $resultArray );
  917.         }
  918.     }
  919.  
  920.     //
  921.     // For each curve, if it is a curve-on-surface, then
  922.     // use the "duplicateCurve" command to create a curve
  923.     // that is not in the underworld.  Then use this new
  924.     // curve for the effect.  The "duplicateCurve"
  925.     // command puts the original curve in the history
  926.     // for the new curve, so changes to the original will
  927.     // still be reflected i nthe new curve.
  928.     //
  929.     {
  930.         if( size($setName) == 0 )
  931.         {
  932.             $setName = "Flow";
  933.         }
  934.  
  935.         int $i;
  936.         for( $i = 0; $i < size($curveArray); $i ++ )
  937.         {
  938.             string $newCurve = "";
  939.             if( isObjectInUnderWorld( $curveArray[$i] ) == 1 )
  940.             {
  941.                 string $duplicateCurve[] = `duplicateCurve -ch 1 -rn 0 -local 0 -name ($setName+"_FlowCurve") $curveArray[$i]`;
  942.                 $newCurve = $duplicateCurve[0];
  943.             }
  944.             else
  945.             {
  946.                 string $duplicateCurve = superDuplicateCurve( $curveArray[$i] );
  947.                 if( $duplicateCurve == "" )
  948.                 {
  949.                     continue;
  950.                 }
  951.                 $newCurve = $duplicateCurve;
  952.             }
  953.  
  954.             $curveArray[$i] = $newCurve;
  955.             setAttr ($newCurve+".template") 1;
  956.             setAttr ($newCurve+".visibility") 0;
  957.         }
  958.     }
  959.  
  960.     $controlSegmentCount = max( $controlSegmentCount, 2 );
  961.     $subSegmentCount = max( $subSegmentCount, 2 );
  962.  
  963.     //
  964.     // For each curve, create the other objects
  965.     //
  966.     {
  967.         int $i;
  968.         for( $i = 0; $i < size($curveArray); $i ++ )
  969.         {
  970.             int $intermediate = isObjectIntermediate( $curveArray[$i] );
  971.             if( $intermediate == 1 )
  972.             {
  973.                 warning("The curve \""+$curveArray[$i]+"\" is an intermediate object.  Not performing the effect for this curve.");
  974.                 continue;
  975.             }
  976.             string $flowSet = flowAlongCurve( $setName, $curveArray[$i], $controlSegmentCount, $subSegmentCount, $attachEmitterToCurve, $emitterRate, $randomMotionSpeed, $lifespan, $goalWeight );
  977.             $resultArray[size($resultArray)] = $flowSet;
  978.         }
  979.     }
  980.  
  981.     //
  982.     // Set the selection to be the groups that were created for each curve.
  983.     //
  984.     select $resultArray;
  985.  
  986.     return( $resultArray );
  987. }
  988.  
  989.  
  990.